package repository

import (
	"blog/internal/model"
	"context"
	"errors"
	"gorm.io/gorm"
	"time"
)

type ArticleRepository interface {
	CreateArticle(ctx context.Context, article *model.Article) error
	GetArticleByID(ctx context.Context, id uint) (*model.Article, error)
	UpdateArticle(ctx context.Context, article *model.Article) error
	DeleteArticleById(ctx context.Context, id uint) error
	ListArticle(ctx context.Context) ([]*model.Article, error)
	ListArticlesByAuthorID(ctx context.Context, authorID uint) ([]*model.Article, error)
	SearchArticlesByTitle(ctx context.Context, keyword string) ([]*model.Article, error)
}

func NewArticleRepository(
	repository *Repository,
) ArticleRepository {
	return &articleRepository{
		Repository: repository,
	}
}

type articleRepository struct {
	*Repository
}

func (r *articleRepository) CreateArticle(ctx context.Context, article *model.Article) error {
	return r.DB(ctx).Create(article).Error
}

func (r *articleRepository) GetArticleByID(ctx context.Context, id uint) (*model.Article, error) {
	var article model.Article
	if err := r.DB(ctx).First(&article, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, err
	}
	return &article, nil
}

func (r *articleRepository) UpdateArticle(ctx context.Context, article *model.Article) error {
	article.UpdatedAt = time.Now()
	err := r.DB(ctx).
		Model(&model.Article{}).
		Where("id = ?", article.ID).
		Select("Title", "Content", "UpdatedAt").
		Updates(article).Error
	if err != nil {
		return err
	}
	return nil
}
func (r *articleRepository) DeleteArticleById(ctx context.Context, id uint) error {
	return r.DB(ctx).Delete(&model.Article{}, id).Error
}

func (r *articleRepository) ListArticle(ctx context.Context) ([]*model.Article, error) {
	var articles []*model.Article
	if err := r.DB(ctx).Find(&articles).Error; err != nil {
		return nil, err
	}
	return articles, nil
}
func (r *articleRepository) ListArticlesByAuthorID(ctx context.Context, authorID uint) ([]*model.Article, error) {
	var articles []*model.Article
	err := r.DB(ctx).
		Where("author_id = ?", authorID).
		Find(&articles).Error
	if err != nil {
		return nil, err
	}
	return articles, nil
}
func (r *articleRepository) SearchArticlesByTitle(ctx context.Context, keyword string) ([]*model.Article, error) {
	var articles []*model.Article
	err := r.DB(ctx).
		Where("article_title LIKE ?", "%"+keyword+"%").
		Find(&articles).Error
	if err != nil {
		return nil, err
	}
	return articles, nil
}
